#define _GNU_SOURCE
#include <netinet/if_ether.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/if_tun.h>
#include <net/if.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
// uint8_t tap1[] = {0x2a, 0xab, 0x43, 0xf6, 0x03, 0xb4};
// uint8_t tap0[] = {0xbe, 0x26, 0x55, 0xa5, 0xce, 0x34};
int ether_pck_len = 50 + sizeof(struct ether_header);
int main()
{
    // 打开tap1网卡接口

    char tap_name[] = "tap1";
    int fd = open("/dev/net/tun", O_RDWR);
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(struct ifreq));
    strncpy(ifr.ifr_ifrn.ifrn_name, tap_name, sizeof(tap_name));
    ifr.ifr_ifru.ifru_flags = IFF_TAP | IFF_NO_PI;
    if (ioctl(fd, TUNSETIFF, &ifr) != 0)
    {
        perror(strerror(errno));
        exit(errno);
    };

    char *data = "helloworld";
    uint16_t len = strlen(data);

    // 准备以太网帧头结构体
    struct ether_header ether_header = {
        .ether_shost = {0x2a, 0xab, 0x43, 0xf6, 0x03, 0xb4},
        .ether_dhost = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
        .ether_type = 50,
    };
    // 准备数据包空间

    char *ether_pck = malloc(ether_pck_len);
    memset(ether_pck, 0, ether_pck_len);
    // 设置数据包以太网帧头
    memcpy(ether_pck, &ether_header, sizeof(struct ether_header));
    // 设置数据包以太网数据
    for (int i = 0; i < len; i++)
    {
        /* code */
        ether_pck[sizeof(struct ether_header) + i] = data[i];
    }
    // 写入tap1网卡接口
    while (1)
    {
        /* code */
        int need_write = ether_pck_len;
        char *p_ether_pck_offset;
        do
        {
            /* code */
            p_ether_pck_offset = ether_pck + (ether_pck_len - need_write);
            int write_count = write(fd, p_ether_pck_offset, need_write);
            need_write -= write_count;
        } while (need_write != 0);
        sleep(1);
    }
    return 0;
}